home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / ddj9304.zip / 1993-APR.ZIP / TEXTED.ASC < prev    next >
Text File  |  1993-02-17  |  8KB  |  223 lines

  1. _TEXT EDITORS: ALGORITHMS AND ARCHITECTURES_
  2. by Ray Valdes
  3.  
  4. [LISTING ONE]
  5.  
  6. /* EditLine() -- The simplest text editing routine */
  7. void EditLine(char* buffer, int max_length, int curr_row)
  8. {
  9.     int c, str_length  = strlen(buffer), curr_column = str_length, 
  10.            insert_mode = TRUE;
  11.     ChangeCursorShape(insert_mode);
  12.     do
  13.     {   vt_ClearLineAt(curr_row,0);
  14.     vt_OutputStringAt(buffer, curr_row,0);
  15.     vt_SetCursorPositionAt(curr_row,curr_column);
  16.     switch(c = vt_GetKeystroke())   /* dispatch on user's keystroke */
  17.     {
  18.          /*-------- keystrokes that terminate the editing session-----*/
  19.          case ESCAPE_KEY:
  20.          case ENTER_KEY:     break;
  21.         /*--------- keystrokes that merely change the cursor position---*/
  22.  
  23.        case HOME_KEY:      curr_column = 0;                break;
  24.         case END_KEY:       curr_column = str_length;           break;
  25.             case LEFT_KEY:      if (curr_column > 0) curr_column--; break;
  26.         case RIGHT_KEY:     if (curr_column < str_length) curr_column++;
  27.                 break;
  28.         case INSERT_KEY:    insert_mode = !insert_mode;
  29.                 ChangeCursorShape(insert_mode);
  30.                 break;
  31.         /*------ keystrokes that alter the contents of the buffer----*/
  32.         case BACKSPACE_KEY: if (curr_column > 0)
  33.                 {
  34.                     movmem( &buffer[curr_column],  /*source*/
  35.                         &buffer[curr_column-1], /*dest*/
  36.                         str_length - curr_column + 1);
  37.                     curr_column--;  
  38.                     str_length--;
  39.                 }
  40.                 break;
  41.          case DELETE_KEY:   if (curr_column < str_length)
  42.                 {
  43.                     movmem( &buffer[curr_column+1], /*source*/
  44.                     &buffer[curr_column],       /*dest*/
  45.                     str_length - curr_column);
  46.                     str_length--;
  47.                  }
  48.                  break;
  49.          default:        if (((c >= ' ') && (c <= '~')) &&
  50.                         (str_length < max_length))
  51.                  {
  52.                     if (insert_mode)
  53.                     {
  54.                         movmem( 
  55.                             &buffer[curr_column],
  56.                         &buffer[curr_column + 1],
  57.                         str_length - curr_column + 1);
  58.                         str_length++;
  59.                     }
  60.                     else if (curr_column >= str_length)
  61.                         str_length++;
  62.                     buffer[curr_column] = c;
  63.                     curr_column++;
  64.                   }
  65.                   break;
  66.          }
  67.          buffer[str_length] = '\0';
  68.     }
  69.  
  70.     while ((c != ENTER_KEY) && (c != ESCAPE_KEY));
  71. }
  72.  
  73. [LISTING TWO]  
  74. /****************************************************************************
  75. Excerpts from BUF_GAP.C--buffer gap manager module. Derived by Ray Valdes from
  76. code by Joseph H. Allen, who wrote in his post to the comp.editors newsgroup
  77. on 9/10/89: "Do whatever you like with this, just leave my name on it."
  78. *****************************************************************************/
  79.  
  80. private unsigned sizeofBuffer;    /* The size of theBuffer */
  81. private char*    thePoint;        /* The point */
  82. private char*    theBuffer;       /* The buffer */
  83. private char*    theEndOfBuffer;  /* First character not in buffer */
  84. private char*    theStartOfGap;   /* Beginning of theStartOfGap */
  85. private char*    theEndOfGap;     /* First character not in theStartOfGap */
  86. private bool     isBufferChanged; /* Set when file has been changed */
  87.  
  88. #define SIZEOF_GAP_INCREMENT   16384  /* Amount that the buffgap grows by */
  89.  
  90. /****************************************************************/    
  91. public bool 
  92. bg_InitializeModule(void)
  93. {   sizeofBuffer = SIZEOF_GAP_INCREMENT;
  94.     theBuffer = (char* ) mem_AllocMem(sizeofBuffer);
  95.     if(!theBuffer) return FALSE;
  96.     thePoint      = theBuffer;
  97.     theStartOfGap = theBuffer;
  98.     theEndOfGap   = theBuffer + SIZEOF_GAP_INCREMENT;
  99.     theEndOfBuffer= theEndOfGap;
  100.     return TRUE;
  101. }
  102. /****************************************************************/    
  103. public void 
  104. bg_ExpandBuffer(unsigned amount)
  105. {
  106.    if( (theEndOfBuffer + amount - theBuffer) > sizeofBuffer)
  107.     {   char* old = theBuffer;
  108.         sizeofBuffer = theEndOfBuffer + amount 
  109.                  + SIZEOF_GAP_INCREMENT - theBuffer;
  110.         theBuffer = (char* ) mem_ReallocMem(theBuffer, sizeofBuffer);
  111.         if(!theBuffer) ProgramError("ReallocMem failed!");
  112.         thePoint       += theBuffer - old;
  113.         theEndOfBuffer += theBuffer - old;
  114.         theStartOfGap  += theBuffer - old;
  115.         theEndOfGap    += theBuffer - old;
  116.     }
  117. }
  118. /****************************************************************/    
  119. public void 
  120. bg_MoveGapToPoint(void)
  121. {
  122.     if(thePoint==theStartOfGap) return;
  123.     if(thePoint==theEndOfGap)  { thePoint = theStartOfGap; return; }
  124.     /*else*/
  125.     if(thePoint < theStartOfGap)
  126.     {   bg_MoveBytes( theEndOfGap - (theStartOfGap-thePoint),
  127.                       thePoint, theStartOfGap - thePoint);
  128.         theEndOfGap   = theEndOfGap-(theStartOfGap-thePoint);
  129.         theStartOfGap = thePoint;
  130.     }
  131.     else
  132.     {   bg_MoveBytes(theStartOfGap,theEndOfGap,thePoint-theEndOfGap);
  133.         theStartOfGap += thePoint-theEndOfGap;
  134.         theEndOfGap    = thePoint;
  135.         thePoint       = theStartOfGap;
  136.     }
  137. }
  138. /****************************************************************/    
  139. public void
  140. bg_ExpandGap(unsigned size)
  141. {   if(size > bg_SizeofGap())
  142.     {
  143.         size += SIZEOF_GAP_INCREMENT;
  144.         bg_ExpandBuffer(size);
  145.         bg_MoveBytes(theEndOfGap+size,
  146.                      theEndOfGap, theEndOfBuffer - theEndOfGap);
  147.         theEndOfGap    += size;
  148.         theEndOfBuffer += size;
  149.     }
  150. }
  151. /****************************************************************/    
  152. public bool 
  153. bg_FindNextNewline(void)
  154. {   while(((thePoint==theStartOfGap) ? (thePoint=theEndOfGap) : (thePoint))
  155.             != theEndOfBuffer)
  156.     {
  157.         if(*thePoint==NEWLINE_CH) return TRUE;
  158.         else thePoint++;
  159.     }
  160.     return FALSE;
  161. }
  162. /****************************************************************/    
  163. public void 
  164. bg_InsertStringAtPoint(char* string, unsigned size)
  165. {   bg_MoveGapToPoint();
  166.     if(size > bg_SizeofGap())    
  167.         bg_ExpandGap(size);
  168.     bg_MoveBytes(theStartOfGap,string,size);
  169.     theStartOfGap += size;
  170.     isBufferChanged = TRUE;
  171. }
  172. /****************************************************************/    
  173. public bool 
  174. bg_CompareString(char* string, unsigned size)
  175. {   char* x;
  176.     if(thePoint==theStartOfGap) thePoint=theEndOfGap;
  177.     if(    (theStartOfGap > thePoint )
  178.         && (theStartOfGap < thePoint + size )
  179.         && (theStartOfGap != theEndOfGap) )
  180.     {
  181.          if(bg_CompareString(string,theStartOfGap-thePoint)) return TRUE;
  182.          else
  183.          {
  184.              x = thePoint;
  185.              thePoint = theEndOfGap;
  186.              if(bg_CompareString(  string + (theStartOfGap-x)
  187.                                  , size - (theStartOfGap-x)))
  188.                   { thePoint=x;  return TRUE;  }
  189.              else { thePoint=x;  return FALSE; }
  190.          }
  191.     }
  192.     else
  193.     {
  194.         x = thePoint;
  195.         do { if(*(x++) != *(string++)) return TRUE; } while(--size);
  196.         return FALSE;
  197.     }
  198. }
  199. /****************************************************************/    
  200. public bool              /*this routine assumes file is already open*/
  201. bg_InsertFile(FILE* file) 
  202. {   unsigned amount; 
  203.     long file_size = filelength(fileno(file));
  204.  
  205.     if(file_size==0L)      return TRUE;
  206.     if(file_size > 32767L) return FALSE;
  207.     
  208.     isBufferChanged = TRUE;
  209.  
  210.     bg_MoveGapToPoint();
  211.     bg_ExpandGap((int)file_size);
  212.  
  213.     amount = fread(theStartOfGap, 1, file_size, file);
  214.     if(amount != file_size)
  215.     { 
  216.         ProgramError("I/O Error on reading file.");
  217.         return FALSE;
  218.     }
  219.     theStartOfGap += amount;
  220.     return TRUE;
  221. }
  222.  
  223.